// ============================================================================
// Crossit
// The main class file for the Crossit game. Crossit is based on the hand held
// LightsOut (TM) game.
//
// History.
// -------
// CLH 31/12/98 Written
// CLH 17/01/99 Correct button numbering to be like real game, make final
//              option button have a red background
// ============================================================================

package com.chrishobson.crossit;
import com.chrishobson.awt.Capplet;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;


@SuppressWarnings("serial")
class CrossStart extends Button {
  public CrossStart(CrossGame g) {
    super("Restart");
    m_game = g;
  }

  public void hit() {
    m_game.start();
  }

  private CrossGame m_game;
}

@SuppressWarnings("serial")
class CrossOption extends Checkbox {
  public CrossOption(CrossGame g, int o, CheckboxGroup cbg) {
    super(Integer.toString(o),o == 1, cbg);
    m_game = g;
    m_opt = o;
    if(m_opt == CrossGame.g_num) {
      setBackground(Color.red);
    }
  }

  public void hit() {
    m_game.option(m_opt);
  }

  private CrossGame m_game;
  private int m_opt;
}

@SuppressWarnings("serial")
class CrossMes extends Label implements CrossMessage {
  public CrossMes(Crossit app) {
    m_app = app;
  }
  public void message(String m) {
    setText(m);
  }
  public void win() {
    m_app.clip();
  }

  private Crossit m_app;
}

@SuppressWarnings("serial")
class CrossBut extends Button implements CrossControl {
  public CrossBut(CrossGame g, int x, int y) {
    // super(Integer.toString(x) + Integer.toString(y));
    super(Integer.toString(y*5 + x + 1));
    m_game = g;
    m_x = x;
    m_y = y;
    m_state = true;
    off();
  }

  public Dimension getPreferredSize() {
    return new Dimension(30,30);
  }

  public void hit() {
    m_game.hit(m_x,m_y);
  }
  public boolean state() {
  // Returns the current state True = On, False = Off
    return m_state;
  }
  
  public void state(boolean s) {
  // Set control to the specified state
  }

  public void toggle() {
    if(m_state) {
      off();
    } else {
      on();
    }
  }

  public void off() {
    if(m_state) {
      setBackground(Color.gray);
      m_state = false;
    }
  }

  public void on() {
    if(!m_state) {
      setBackground(Color.red);
      m_state = true;
    }
  }

  private boolean m_state;
  private int m_x;
  private int m_y;
  private CrossGame m_game;
}

@SuppressWarnings("serial")
public class Crossit extends Capplet {

  public void init() {
    CrossGame game = new CrossGame();;
    int xl = CrossGame.g_x;
    int yl = CrossGame.g_y;
    CrossControl controls[][] = new CrossControl[xl][yl];

    Panel p = new Panel();

    ActionListener al = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
	((CrossBut)e.getSource()).hit();
      }
    };

    for(int y = 0; y < yl; ++y) {
      for(int x = 0; x < xl; ++x) {
	CrossBut b = new CrossBut(game,x,y);
	controls[x][y] = b;
	b.addActionListener(al);
	p.add(b);
      }
    }
    p.setLayout(new GridLayout(yl,xl,1,1));
    add(p);
    //
    // Make the checkbox for the different games
    // 
    p = new Panel();
    CheckboxGroup cbg = new CheckboxGroup();
    ItemListener ie = new ItemListener () {
      public void itemStateChanged(ItemEvent e) {
	if(e.getStateChange() == ItemEvent.SELECTED) {
	  ((CrossOption)e.getSource()).hit();
	}
      }
    };

    for(int i = 1; i <= CrossGame.g_num; ++i) {
      CrossOption opt = new CrossOption(game,i,cbg);
      opt.addItemListener(ie);
      p.add(opt);
    }
    p.setLayout(new GridLayout((CrossGame.g_num - 1)/5 + 1,5));
    add(p);
    //
    // The start button
    //
    CrossStart start = new CrossStart(game);
    add(start);
    start.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
	((CrossStart)e.getSource()).hit();
      }
    });
    CrossMes mes = new CrossMes(this);
    add(mes);

    game.set_controls(mes,controls);
    game.start();
  }

  public void clip() {
    if(m_clip == null) {
      m_clip = getJarSound("/sounds/drip.au");
    }
    if(m_clip != null) {
      m_clip.play();
    }
  }
  
  private AudioClip m_clip;
}
